

cc.MaskNode = cc.Node.extend({
	
	_DebugDraw:false,
	
	init:function (W, H) {
		this.setAnchorPoint(cc.p(0.0, 0.0));
		this.setContentSize(cc.size(W,H));
		return true;
	},

	activeDebugDraw:function(b){
		this._DebugDraw = b;
	},
	
	visit:function (ctx) {
        // quick return if not visible
        if (!this._isVisible) {
            return;
        }

        var context = ctx || cc.renderContext;
        var i;

        if (cc.renderContextType == cc.CANVAS) {
            context.save();
            this.transform(context);
			
			ctx.beginPath();
            ctx.moveTo(0,0);
            ctx.lineTo(this._contentSize.width, 0);
            ctx.lineTo(this._contentSize.width, -this._contentSize.height );
            ctx.lineTo(0, -this._contentSize.height );
            ctx.lineTo(0,0);
            ctx.closePath();
			ctx.clip();
			
			if(this._DebugDraw)
			{
				ctx.fillStyle = "blue";
				ctx.fillRect(0, 0, this._contentSize.width, -this._contentSize.height);
			}
            
          
			

            if (this._children && this._children.length > 0) {
                this.sortAllChildren();
                // draw children zOrder < 0
                for (i = 0; i < this._children.length; i++) {
                    if (this._children[i] && this._children[i]._zOrder < 0) {
                        this._children[i].visit(context);
                    } else {
                        break;
                    }
                }
                //if (this._isInDirtyRegion()) {
                // self draw
                this.draw(context);
                //}
                // draw children zOrder >= 0
                if (this._children) {
                    for (; i < this._children.length; i++) {
                        if (this._children[i] && this._children[i]._zOrder >= 0) {
                            this._children[i].visit(context);
                        }
                    }
                }
            } else {
                //if (this._isInDirtyRegion()) {
                // self draw
                this.draw(context);
                //}
            }
            this._orderOfArrival = 0;
            context.restore();
        } else {
            if (this._grid && this._grid.isActive()) {
                this._grid.beforeDraw();
            }

            this.transform(context);
            if (this._children && this._children.length > 0) {
                this.sortAllChildren();
                // draw children zOrder < 0
                for (i = 0; i < this._children.length; i++) {
                    if (this._children[i] && this._children[i]._zOrder < 0) {
                        this._children[i].visit(context);
                    } else {
                        break;
                    }
                }

                //if (this._isInDirtyRegion()) {
                // self draw
                this.draw(context);
                //}

                // draw children zOrder >= 0
                if (this._children) {
                    for (; i < this._children.length; i++) {
                        if (this._children[i] && this._children[i]._zOrder >= 0) {
                            this._children[i].visit(context);
                        }
                    }
                }
            } else {
                //if (this._isInDirtyRegion()) {
                // self draw
                this.draw(context);
                //}
            }

            this._orderOfArrival = 0;

            if (this._grid && this._grid.isActive()) {
                this._grid.afterDraw(this);
            }

            context.restore();
        }
    },
	
});

cc.MaskNode.create = function (W, H) {
    var _node = new cc.MaskNode();
	_node.init(W,H);
	return _node;
};


// CustomSprite

cc.CustomSprite = cc.Sprite.extend(/** @lends cc.Sprite# */{
	
	init:function () {
		this._super();
		this.setAnchorPoint(cc.p(0.0, 0.0));
		return true;
	},

	initWithTexture:function (texture, rect, rotated) {
		this._super(texture, rect, rotated);
		this.setAnchorPoint(cc.p(0.0, 0.0));
		return true;
	},
});
cc.CustomSprite.create = function (fileName, rect) {
    var argnum = arguments.length;
    var sprite = new cc.CustomSprite();
    if (argnum < 2) {
        if (sprite && sprite.initWithFile(fileName)) {
            return sprite;
        }
        return null;
    } else {
        if (sprite && sprite.initWithFile(fileName, rect)) {
            return sprite;
        }
        return null;
    }
};


// MenuCustom

cc.MenuCustom = cc.Menu.extend({

	_itemForTouch:function (touch) {
        var touchLocation = touch.getLocation();

        if (this._children && this._children.length > 0) {
            for (var i = 0; i < this._children.length; i++) {
                if (this._children[i].isVisible() && this._children[i].isEnabled()) {
                    var local = this._children[i].convertToNodeSpace(touchLocation);
                    var r = this._children[i].rect();
                    if (cc.Rect.CCRectContainsPoint(r, local)) {
                        return this._children[i];
                    }
                }
            }
        }

        return null;
    },
});

cc.MenuCustom.create = function (/*Multiple Arguments*/) {
    var ret = new cc.MenuCustom();

    if (arguments.length == 0) {
        ret.initWithItems(null, null);
    } else if (arguments.length == 1) {
        if (arguments[0] instanceof Array) {
            ret.initWithArray(arguments[0]);
            return ret;
        }
    }
    ret.initWithItems(arguments);
    return ret;
};


// MenuItemNode
 
 var extendBoundingBox = function (BB, childBB)
 {
	var x1 = ( cc.Rect.CCRectGetMinX(BB) < cc.Rect.CCRectGetMinX(childBB) ) ? cc.Rect.CCRectGetMinX(BB) : cc.Rect.CCRectGetMinX(childBB);
	var y1 = ( cc.Rect.CCRectGetMinY(BB) < cc.Rect.CCRectGetMinY(childBB) ) ? cc.Rect.CCRectGetMinY(BB) : cc.Rect.CCRectGetMinY(childBB);

	var x2 = ( cc.Rect.CCRectGetMaxX(BB) > cc.Rect.CCRectGetMaxX(childBB) ) ? cc.Rect.CCRectGetMaxX(BB) : cc.Rect.CCRectGetMaxX(childBB);
	var y2 = ( cc.Rect.CCRectGetMaxY(BB) > cc.Rect.CCRectGetMaxY(childBB) ) ? cc.Rect.CCRectGetMaxY(BB) : cc.Rect.CCRectGetMaxY(childBB);
	
	return new cc.Rect(x1, y1, x2 - x1, y2 - y1);
 }
 
var getRecursiveBoundingBox = function (Node) {
	var BB = Node.getBoundingBox();

	for (var i=0;i<Node.getChildrenCount();i++)
	{ 
		var childBB = getRecursiveBoundingBox( Node.getChildren()[i] );
		if( BB && childBB ){
			BB = extendBoundingBox(BB,childBB);
		}
	}
	
	return BB;
}

var setRecusiveAnchor = function (Node, NewAnchor) {
	Node.setAnchorPoint( NewAnchor );
	
	for (var i=0;i<Node.getChildrenCount();i++)
	{ 
		setRecusiveAnchor( Node.getChildren()[i], NewAnchor );
	}
}
 
cc.MenuItemNode = cc.MenuItem.extend(/** @lends cc.MenuItemSprite# */{

    _normalImage:null,

    /**
     * @return {cc.Node}
     */
    getNormalImage:function () {
        return this._normalImage;
    },

    /**
     * @param {cc.Node} normalImage
     */
    setNormalImage:function (normalImage) {
        if (this._normalImage == normalImage) {
            return;
        }
        if (normalImage) {
            this.addChild(normalImage, 0, cc.NORMAL_TAG);
        }
        if (this._normalImage) {
            this.removeChild(this._normalImage, true);
        }

        this._normalImage = normalImage;
        this._updateImagesVisibility();
    },
    _selectedImage:null,

    /**
     * @return {cc.Node}
     */
    getSelectedImage:function () {
        return this._selectedImage;
    },

    /**
     * @param {cc.Node} selectedImage
     */
    setSelectedImage:function (selectedImage) {
        if (this._selectedImage == selectedImage)
            return;

        if (selectedImage) {
            this.addChild(selectedImage, 0, cc.SELECTED_TAG);
        }

        if (this._selectedImage) {
            this.removeChild(this._selectedImage, true);
        }

        this._selectedImage = selectedImage;
        this._updateImagesVisibility();
    },
    _disabledImage:null,

    /**
     * @return {cc.Sprite}
     */
    getDisabledImage:function () {
        return this._disabledImage;
    },

    /**
     * @param {cc.Node} disabledImage
     */
    setDisabledImage:function (disabledImage) {
        if (this._disabledImage == disabledImage)
            return;

        if (disabledImage) {
            this.addChild(disabledImage, 0, cc.DISABLE_TAG);
        }

        if (this._disabledImage) {
            this.removeChild(this._disabledImage, true);
        }

        this._disabledImage = disabledImage;
        this._updateImagesVisibility();
    },

    /**
     * @param {cc.Node} normalSprite
     * @param {cc.Node} selectedSprite
     * @param {cc.Node} disabledSprite
     * @param {cc.Node} target
     * @param {function|String} selector
     * @return {Boolean}
     */
    initWithNormalNode:function (normalNode, selectedNode, disabledNode, target, selector) {
        this.initWithCallback(target, selector);
        this.setNormalImage(normalNode);
        this.setSelectedImage(selectedNode);
        this.setDisabledImage(disabledNode);
        
        return true;
    },

    /**
     * menu item is selected (runs callback)
     */
    selected:function () {
        this._super();
        if (this._normalImage) {
            if (this._disabledImage) {
                this._disabledImage.setVisible(false);
            }

            if (this._selectedImage) {
                this._normalImage.setVisible(false);
                this._selectedImage.setVisible(true);
            }
            else {
                this._normalImage.setVisible(true);
            }
        }
    },

    /**
     * menu item goes back to unselected state
     */
    unselected:function () {
        this._super();

        if (this._normalImage) {
            this._normalImage.setVisible(true);

            if (this._selectedImage) {
                this._selectedImage.setVisible(false);
            }

            if (this._disabledImage) {
                this._disabledImage.setVisible(false);
            }
        }
    },

    /**
     * @param {Boolean} bEnabled
     */
    setEnabled:function (bEnabled) {
        if (this._isEnabled != bEnabled) {
            this._super(bEnabled);
            this._updateImagesVisibility();
        }
    },

    _updateImagesVisibility:function () {
		if (this._isEnabled) {
            if (this._normalImage)
                this._normalImage.setVisible(true);
            if (this._selectedImage)
                this._selectedImage.setVisible(false);
            if (this._disabledImage)
                this._disabledImage.setVisible(false);
        } else {
            if (this._disabledImage) {
                if (this._normalImage)
                    this._normalImage.setVisible(false);
                if (this._selectedImage)
                    this._selectedImage.setVisible(false);
                if (this._disabledImage)
                    this._disabledImage.setVisible(true);
            } else {
                if (this._normalImage)
                    this._normalImage.setVisible(true);
                if (this._selectedImage)
                    this._selectedImage.setVisible(false);
                if (this._disabledImage)
                    this._disabledImage.setVisible(false);
            }
        }
    },
	
	// override rect function from cc.MenuItem
	/**
     * return rect value of cc.MenuItem
     * @return {cc.Rect}
     */
    rect:function () {
		var BB2 = getRecursiveBoundingBox( this._normalImage );
		return BB2;
    },
	
});

/**
 * create a menu item from Node
 * @param {cc.Node} normal normal state image
 * @param {cc.Node|Null} selected selected state image
 * @param {cc.Node|Null} three disabled state image OR target node
 * @param {String|function|cc.Node|Null} four callback function name in string or actual function, OR target Node
 * @param {String|function|Null} five callback function name in string or actual function
 * @return {cc.MenuItemSprite}
 * @example
 * // Example
 * var item = cc.MenuItemSprite.create(normalImage)//create a menu item from a sprite with no functionality
 *
 * var item = cc.MenuItemSprite.create(normalImage, selectedImage)//create a menu Item, nothing will happen when clicked
 *
 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, disabledImage)//same above, but with disabled state image
 *
 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, targetNode, 'callback')//create a menu item, when clicked runs targetNode.callback()
 *
 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, disabledImage, targetNode, targetNode.callback)
 * //same as above, but with disabled image, and passing in callback function
 */
cc.MenuItemNode.create = function (normalSprite, selectedSprite, three, four, five) {
    var len = arguments.length;
    var normalSprite = arguments[0], selectedSprite = arguments[1], disabledImage, target, callback;
    var ret = new cc.MenuItemNode();
    //when you send 4 arguments, five is undefined
    if (len == 5) {
        disabledImage = arguments[2], target = arguments[3], callback = arguments[4]
    }
    else if (len == 4) {
        target = arguments[2], callback = arguments[3];
    }
    else if (len <= 3) {
        disabledImage = arguments[2];
    }
	
    ret.initWithNormalNode(normalSprite, selectedSprite, disabledImage, target, callback);
    return ret;
};

